************************************************************************************************************************
*									Reproduction code for: Blocking the Radical Right: 								   *	
*			 Evidence from Strategic Candidate Voting Against the AfD in Germany's 2025 Federal Election, Study I	   *	
*											 Sven Hillen & Jessica Kuhlmann 										   *
*											Politische Vierteljahresschrift 										   *
************************************************************************************************************************

/*
Instructions:
This do-file reproduces all findings reported in Study I of the article listed above.
To produce the findings, do the following:

1. Install ados and graph schemes used (if necessary), as follows
	ssc install fre
	ssc install estout
	ssc install coefplot
	ssc install schemepack, replace all	
2. Download dataset from our reproduction archive: final_dataset
3. Run the code below on the dataset 
*/


*** set working directory



**# Bookmark #1
********************************************************************************
****************************** General Settings ********************************
********************************************************************************
	set more off, perm
	version 18.5
	set scheme white_tableau
	graph set window fontface "Times New Roman"


**# Bookmark #2
********************************************************************************
************************ Open data *************************
********************************************************************************
use final_dataset.dta, clear

	
**# Bookmark #3
********************************************************************************
********************* Regression analysis: District Level **********************
********************************************************************************


***** Analysis 1: Candidate vote fragmentation

	
	* AfD 2025
	reg fragmentation c.AfD_Erststimmen_100 ///
		i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes, vce(cluster Bundesland)
			eststo AfD_1	
		gen sample = 1 if e(sample)
					
		* Interaction
		reg fragmentation c.AfD_Erststimmen_100##c.afd_competitive_gap ///
			i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
			, vce(cluster Bundesland)
				eststo AfD_2

			// Conditional effect
				fre afd_competitive_gap if e(sample)
			margins, dydx(AfD_Erststimmen_100) at(afd_competitive_gap=(0(1)35))		
			marginsplot, addplot(hist afd_competitive_gap if e(sample) ///
				, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
				ylabel(none, axis(2)) xlabel(0 (5) 35, gmin gmax) fcolor(%30) lcolor(%30)) ///
				recast(line) recastci(rarea) ///
				yline(0) legend(off) title("Effect on ENC", margin(b=5)) ytitle("") xtitle("Competitive gap AfD") ///
				name(Fragmentation, replace)				
	
	* CDU/CSU
	reg fragmentation c.Union_Erststimmen_100 ///
		i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes, vce(cluster Bundesland)
			eststo Union
	
	* SPD
	reg fragmentation c.SPD_Erststimmen_100 ///
		i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes, vce(cluster Bundesland)
			eststo SPD
				
	* Greens
	reg fragmentation c.Grüne_Erststimmen_100 ///
		i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes, vce(cluster Bundesland)
			eststo Grüne
				
	* The Left
	reg fragmentation c.Linke_Erststimmen_100 ///
		i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes, vce(cluster Bundesland)
			eststo Linke	
				
				
	*** Robustness Checks
				
		* AfD Erststimmenanteil 2021
			pwcorr AfD_Erststimmen_100 AfD_Erststimmen2021_100			
		reg fragmentation c.AfD_Erststimmen2021_100 ///
				i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo AfD2021_1
							
			* Interaction
			reg fragmentation c.AfD_Erststimmen2021_100##c.afd_competitive_gap ///
				i.incumbent c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo AfD2021_2

				// Conditional effect
				margins, dydx(AfD_Erststimmen2021_100) at(afd_competitive_gap=(0(1)35))			
				marginsplot, addplot(hist afd_competitive_gap if e(sample) ///
					, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
					ylabel(none, axis(2)) xlabel(0 (5) 35, gmin gmax) fcolor(%30) lcolor(%30)) ///
					recast(line) recastci(rarea) ///
					yline(0) legend(off) title("Effect on ENC", margin(b=5)) ytitle("") xtitle("Competitive gap AfD") ///
					name(Fragmentation2021, replace)					
					
		* AfD Erstimmenanteil YouGov
			pwcorr AfD_Erststimmen_100 AfD_Erststimmen2021_100 AfDShare	

		reg fragmentation c.AfDShare ///
			i.incumbent c.margin_top2_YG c.ratio_SMD_PR c.Diff_valid_votes ///
			if sample == 1, vce(cluster Bundesland)
				eststo AfDYouGov_1
					
			* Interaction
			reg fragmentation c.AfDShare##c.afd_competitive_gapYG ///
				i.incumbent c.margin_top2_YG c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo AfDYouGov_2
					
				// Conditional Effect
					fre afd_competitive_gapYG if e(sample)
				margins, dydx(AfDShare) at(afd_competitive_gapYG=(0(1)37))						
				marginsplot, addplot(hist afd_competitive_gapYG if e(sample) ///
					, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
					ylabel(none, axis(2)) xlabel(0 (5) 37, gmin gmax) fcolor(%30) lcolor(%30)) ///
					recast(line) recastci(rarea) ///
					yline(0) legend(off) title("Effect on ENC", margin(b=5)) ytitle("") xtitle("Competitive gap AfD, YouGov") ///
					name(FragmentationYG, replace)	
	
						
		*** Figure 2: Marginal effects of the main parties' candidate votes on the ENC in the districts
			coefplot AfD_1 AfD2021_1 AfDYouGov_1 Union SPD Grüne Linke, ///
				keep(AfD_Erststimmen_100 AfD_Erststimmen2021_100 AfDShare Union_Erststimmen_100 ///
					SPD_Erststimmen_100 Grüne_Erststimmen_100 Linke_Erststimmen_100) ///
				horizontal xline(0) legend(off) ///
				coeflabel(AfD_Erststimmen_100="Candidate vote AfD 2025" ///
						AfD_Erststimmen2021_100="Candidate vote AfD 2021" ///
						AfDShare="Candidate vote AfD YouGov" /// 
						Union_Erststimmen_100="Candidate vote CDU/CSU 2025" ///
						SPD_Erststimmen_100="Candidate vote SPD 2025" /// 
						Grüne_Erststimmen_100="Candidate vote Greens 2025" ///
						Linke_Erststimmen_100="Candidate vote The Left 2025", wrap(15)) ///
				ciopts(lcolor("34 113 178")) mcolor("34 113 178") ///
				groups(AfD_Erststimmen_100 AfD_Erststimmen2021_100 AfDShare = "AfD measures" ///
				Union_Erststimmen_100 SPD_Erststimmen_100 Grüne_Erststimmen_100 ///
					Linke_Erststimmen_100 = "Other parties") ///
				name(coefplotfragmen, replace)


				
***** Analysis 2: Overperformance 

	* AfD 2025
	reg overperformance_gegenkandidat c.AfD_Erststimmen_100 ///
		i.incumbent_rival i.afd_amtsinhaber c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
		, vce(cluster Bundesland)
			eststo overp1
	
	* Interaction
		reg overperformance_gegenkandidat c.AfD_Erststimmen_100##c.afd_competitive_gap ///
			i.incumbent_rival i.afd_amtsinhaber c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
			, vce(cluster Bundesland)
				eststo overp2
					
		// Conditional Effect
		margins, dydx(AfD_Erststimmen_100) at(afd_competitive_gap=(0(1)35))			
		marginsplot, addplot(hist afd_competitive_gap if e(sample) ///
			, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
			ylabel(none, axis(2)) xlabel(0 (5) 35, gmin gmax) fcolor(%30) lcolor(%30)) ///
			recast(line) recastci(rarea) ///
			yline(0) legend(off) title("Effect on Overperformance", margin(b=5)) ytitle("") xtitle("Competitive gap AfD") ///
			name(Overper, replace)
		

		*** Figure 3: Conditional effects AfD candidate vote on the ENC and the overperformance strongest non-AfD competitor
			graph combine Fragmentation Overper, ///
				col(2) imargin(vsmall) iscale(*1.2) ysize(4.5) name(Figure3, replace)
			

	*** Robustness Checks
			
		* AfD-Erststimmenanteil 2021
		reg overperformance_gegenkandidat c.AfD_Erststimmen2021_100 ///
			i.incumbent_rival i.afd_amtsinhaber c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
			if sample == 1, vce(cluster Bundesland)
				eststo overp1_2021
							
			* Interaction
			reg overperformance_gegenkandidat c.AfD_Erststimmen2021_100##c.afd_competitive_gap ///
				i.incumbent_rival i.afd_amtsinhaber c.margin_top2 c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo overp2_2021
				
				// Conditional Effect
				margins, dydx(AfD_Erststimmen2021_100) at(afd_competitive_gap=(0(1)35))
				marginsplot, addplot(hist afd_competitive_gap if e(sample) ///
					, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
					ylabel(none, axis(2)) xlabel(0 (5) 35, gmin gmax) fcolor(%30) lcolor(%30)) ///
					recast(line) recastci(rarea) ///
					yline(0) legend(off) title("Effect on Overperformance", margin(b=5)) ytitle("") xtitle("Competitive gap AfD") ///
					name(Overper_2021, replace)
	
											
		* AfD-Erststimmenanteil YouGov
			reg overperformance_gegenkandidat c.AfDShare ///
				i.incumbent_rival i.afd_amtsinhaber c.margin_top2_YG c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo overp1_YG
					
			* Interaction
			reg overperformance_gegenkandidat c.AfDShare##c.afd_competitive_gapYG ///
				i.incumbent_rival i.afd_amtsinhaber c.margin_top2_YG c.ratio_SMD_PR c.Diff_valid_votes ///
				if sample == 1, vce(cluster Bundesland)
					eststo overp2_YG
				
				// Conditional Effect
				margins, dydx(AfDShare) at(afd_competitive_gapYG=(0(1)37))
				marginsplot, addplot(hist afd_competitive_gapYG if e(sample) ///
					, percent yaxis(2) yscale(alt range(0 50) lstyle(none) axis(2)) ytitle("", size(zero) axis(2)) ///
					ylabel(none, axis(2)) xlabel(0 (5) 37, gmin gmax) fcolor(%30) lcolor(%30)) ///
					recast(line) recastci(rarea) ///
					yline(0) legend(off) title("Effect on Overperformance", margin(b=5)) ytitle("") xtitle("Competitive gap AfD, YouGov") ///
					name(Overper_YG, replace)
							
		
		*** Figure A1
		graph combine Fragmentation2021 Overper_2021, ///
			col(2) imargin(vsmall) iscale(*1.2) ysize(4.5) name(FigStud1A1, replace)
			
		*** Figure A2
		graph combine FragmentationYG Overper_YG, /// 
			col(2) imargin(vsmall) iscale(*1.2) ysize(4.5) name(FigStud1A2, replace)

		
	***** Write regression tables
	
		* Table 1
		esttab AfD_1 AfD_2 overp1 overp2 using "DistictResults.rtf" ///
			, b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace

		* Table A1
		esttab AfD2021_1 AfD2021_2 overp1_2021 overp2_2021 using "DistictResults_A1.rtf" ///
			, b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace
		
		* Table A2
		esttab AfDYouGov_1 AfDYouGov_2 overp1_YG overp2_YG using "DistictResults_A2.rtf" ///
			, b(a2) se(a2) star(* 0.1 ** 0.05 *** 0.01) label nogaps nodepvars replace